home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / ply15dat.zip / COIL.C < prev    next >
C/C++ Source or Header  |  1992-10-04  |  6KB  |  193 lines

  1. /*
  2.  * coil.c - Create a coil of n turns between two points in space
  3.  *
  4.  * Alexander Enzmann
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #ifdef MAC
  11. #include <console.h>
  12. #endif
  13. #include "def.h"
  14. #include "lib.h"
  15.  
  16. static void
  17. determine_coil_point(COORD4 *pos, COORD4 *norm,
  18.              double theta, double phi, double r0, double r1, double d0)
  19. {
  20.    COORD4 v0, v1, vd;
  21.    double len;
  22.  
  23.    /* Center of the coil */
  24.    SET_COORD4(v0, r0 * cos(theta), r0 * sin(theta), d0, 1.0);
  25.  
  26.    /* Point on the coil */
  27.    SET_COORD4(*pos, (r0 + r1 * sin(phi)) * cos(theta),
  28.             (r0 + r1 * sin(phi)) * sin(theta),
  29.             (r1 * cos(phi)) + d0,
  30.             1.0);
  31.  
  32.    /* Direction from center to point */
  33.    SUB3_COORD(vd, *pos, v0);
  34.    len = lib_normalize_coord3(&vd);
  35.  
  36.    v0.x = r1*cos(phi)*cos(theta);
  37.    v1.x = -(r0 + r1*sin(phi))*sin(theta);
  38.  
  39.    v0.y = r1*cos(phi)*sin(theta);
  40.    v1.y = (r0 + r1*sin(phi))*cos(theta);
  41.  
  42.    v0.z = -r1*sin(phi);
  43.    v1.z = 0.0;
  44.  
  45.    CROSS(*norm, v0, v1);
  46.    len = lib_normalize_coord3(norm);
  47.  
  48.    len = DOT_PRODUCT(*norm, vd);
  49.    if (len < 0.0) {
  50.       norm->x *= -1.0;
  51.       norm->y *= -1.0;
  52.       norm->z *= -1.0;
  53.       }
  54.    norm->w = 0.0;
  55. }
  56.  
  57. static void
  58. generate_coil(COORD4 *start, COORD4 *end,
  59.          int turns, int step_per_turn, int step_per_side,
  60.          double r0, double r1)
  61. {
  62.    int i, j, k;
  63.    COORD4 p0, p[4], n0, n[4];
  64.    COORD4 dir;
  65.    MATRIX trans, itrans;
  66.    double dist, u0, u1, v0, v1, d0, d1, len;
  67.    double deltad, deltau, deltav;
  68.  
  69.    SUB3_COORD(dir, *end, *start);
  70.    dist = lib_normalize_coord3(&dir);
  71.  
  72.    /* Figure out the transform to get from the parametrically defined
  73.       coil to the start-end line */
  74.    lib_create_canonical_matrix(itrans, trans, start, &dir);
  75.  
  76.    deltad = dist / (double)(turns * step_per_turn);
  77.    deltau = 2.0 * PI / (double)step_per_turn;
  78.    deltav = 2.0 * PI / (double)step_per_side;
  79.  
  80.    /* Start generating the triangles in the coil */
  81.    for (i=0,d0=0.0;i<turns;i++) {
  82.       for (j=0;j<step_per_turn;j++,d0+=deltad) {
  83.          d1 = d0 + deltad;
  84.      u0 = (double)j * deltau;
  85.      u1 = u0 + deltau;
  86.      for (k=0;k<step_per_side;k++) {
  87.         v0 = (double)k * deltav;
  88.         v1 = v0 + deltav;
  89.  
  90.         /* Make the vertices of this patch on the coil */
  91.         determine_coil_point(&p0, &n0, u0, v0, r0, r1, d0);
  92.         lib_transform_coord(&p[0], &p0, trans);
  93.         lib_transform_coord(&n[0], &n0, trans);
  94.         determine_coil_point(&p0, &n0, u0, v1, r0, r1, d0);
  95.         lib_transform_coord(&p[1], &p0, trans);
  96.         lib_transform_coord(&n[1], &n0, trans);
  97.         determine_coil_point(&p0, &n0, u1, v1, r0, r1, d1);
  98.         lib_transform_coord(&p[2], &p0, trans);
  99.         lib_transform_coord(&n[2], &n0, trans);
  100.  
  101.         /* Make triangles out of the vertices */
  102.         lib_output_polypatch(3, &p[0], &n[0]);
  103.  
  104.         COPY_COORD4(p[1], p[2]); COPY_COORD4(n[1], n[2]);
  105.         determine_coil_point(&p0, &n0, u1, v0, r0, r1, d1);
  106.         lib_transform_coord(&p[2], &p0, trans);
  107.         lib_transform_coord(&n[2], &n0, trans);
  108.         lib_output_polypatch(3, &p[0], &n[0]);
  109.         }
  110.      }
  111.       }
  112. }
  113.  
  114. static void
  115. generate_cyl_coil(COORD4 *start, COORD4 *end,
  116.          int turns, int step_per_turn,
  117.          double r0, double r1)
  118. {
  119.    int i, j, k;
  120.    COORD4 p, p0, p1, n0;
  121.    COORD4 dir;
  122.    MATRIX trans, itrans;
  123.    double dist, u0, u1, d0, d1, len;
  124.    double deltad, deltau;
  125.  
  126.    SUB3_COORD(dir, *end, *start);
  127.    dist = lib_normalize_coord3(&dir);
  128.  
  129.    /* Figure out the transform to get from the parametrically defined
  130.       coil to the start-end line */
  131.    lib_create_canonical_matrix(itrans, trans, start, &dir);
  132.  
  133.    deltad = dist / (double)(turns * step_per_turn);
  134.    deltau = 2.0 * PI / (double)step_per_turn;
  135.  
  136.    /* Start generating the cylinders making up the coil */
  137.    for (i=0,d0=0.0;i<turns;i++) {
  138.       for (j=0;j<step_per_turn;j++,d0+=deltad) {
  139.          d1 = d0 + deltad;
  140.      u0 = (double)j * deltau;
  141.      u1 = u0 + deltau;
  142.      determine_coil_point(&p, &n0, u0, 0.0, r0, 0.0, d0);
  143.      lib_transform_coord(&p0, &p, trans);
  144.      p0.w = r1;
  145.      determine_coil_point(&p, &n0, u1, 0.0, r0, 0.0, d1);
  146.      lib_transform_coord(&p1, &p, trans);
  147.      p1.w = r1;
  148.      lib_output_cylcone(&p0, &p1, OUTPUT_CURVES);
  149.      lib_output_sphere(&p0, OUTPUT_CURVES);
  150.      }
  151.       }
  152.    /* Cap the end */
  153.    lib_output_sphere(&p1, OUTPUT_CURVES);
  154. }
  155.  
  156. void
  157. main(int argc, char *argv[])
  158. {
  159.     COORD4  back_color, coil_color, dir;
  160.     COORD4  center_pt, end_pt, light;
  161.     COORD4  from, at, up;
  162.  
  163.     MATRIX m1, m2;
  164.  
  165.    /* We are using Polyray */
  166.    lib_set_raytracer(OUTPUT_POLYRAY);
  167.  
  168.     /* output viewpoint */
  169.     SET_COORD(from, 0.0, 3.0,-8.0);
  170.     SET_COORD(at,   0.0, 0.0, 5.0);
  171.     SET_COORD(up,   0.0, 1.0, 0.0);
  172.     lib_output_viewpoint( &from, &at, &up, 30.0, 1.0, 1.0, 256, 256);
  173.  
  174.     /* output background color - dark blue */
  175.     SET_COORD( back_color, 0.039, 0.18, 0.376 ) ;
  176.     lib_output_background_color( &back_color ) ;
  177.  
  178.     /* output light source */
  179.     SET_COORD4( light,-10.0, 10.0,-20.0, 0.7) ;
  180.     lib_output_light( &light ) ;
  181.     SET_COORD4( light, 10.0, 10.0,-20.0, 0.7) ;
  182.     lib_output_light( &light ) ;
  183.  
  184.     /* output coil color - red */
  185.     SET_COORD( coil_color, 1.0, 0.2, 0.2 ) ;
  186.     lib_output_color(&coil_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0) ;
  187.  
  188.     /* compute and output coil */
  189.     SET_COORD4(center_pt,-1.0,-1.0, 0.0, 1.0);
  190.     SET_COORD4(end_pt, 1.0, 3.0, 4.0, 1.0);
  191.     generate_cyl_coil(¢er_pt, &end_pt, 5, 12, 1.0, 0.3);
  192. }
  193.